#include "StdAfx.h"
#include "Database.h"

#include "dft.h"

template <typename T>
void Serialize(CArchive &archive, T &elem)
{
	// ar trebuii sa aruncam o exceptie
	// e o functie dummy
}

// functii interne pentru serializarea de stl list si FourierTerm
template <typename T> 
void Serialize(CArchive &archive, std::list<T> &lst)
{
	if (archive.IsStoring()) 
	{
		archive << lst.size();

		for (std::list<T>::iterator it = lst.begin(); it != lst.end(); it++)
		{
			Serialize(archive, *it);
		}
	} else
	{
		unsigned int n;

		archive >> n;
		for (; n; n--)
		{
			T elem;
			Serialize(archive, elem);
			lst.push_back(elem);
		}

	}
}

template <>
void Serialize(CArchive &archive, Centroid &centroid)
{
	Serialize(archive, centroid.serie);
	
	if (archive.IsStoring())
	{
		archive << centroid.label;
		archive << centroid.size;
	}
	else
	{
		archive >> centroid.label;
		archive >> centroid.size;
	}
}

template <>
void Serialize(CArchive &archive, FourierTerm &term)
{
	if (archive.IsStoring())
	{
		archive << term.first.first;
		archive << term.first.second;
		archive << term.second;
	}
	else
	{
		archive >> term.first.first;
		archive >> term.first.second;
		archive >> term.second;
	}
}

IMPLEMENT_SERIAL( Database, CObject, 1 )


// nota: strategia de scriere a bazei de date e neoptima
//		 se deschide fisierul baza de date la crearea obiectului 
//		 si se inchide la distrugerea lui

Database::Database() : m_file_name(0)
{
}

Database::Database(const TCHAR* file_name) : m_file_name(file_name)
{
	CFileStatus file_status;

	if ( CFile::GetStatus(file_name, file_status) )
	{
		m_file.Open(file_name, CFile::modeReadWrite);

		CArchive read_archive(&m_file, CArchive::load);
		this->Serialize(read_archive);
		read_archive.Close();

		// mergi la inceput pentru a rescrie fisierul
		m_file.SeekToBegin();
	}
	else
	{
		CFileException exception;
		
		m_file.Open( file_name, CFile::modeCreate | CFile::modeReadWrite, &exception );
	}
}

Database::~Database(void)
{
	if (!m_file_name)
		return;

	CArchive write_archive(&m_file, CArchive::store);
	this->Serialize(write_archive);
	write_archive.Close();

	m_file.Close();
}

void Database::Serialize( CArchive& archive )
{
	CObject::Serialize( archive );

	::Serialize(archive, m_list);
}

CentroidList& Database::centroid_list()
{
	return m_list;
}